import { uuidv4 } from "@ey-utils/utils/utils";
import { Spin, Tabs, Space, Button, Popover } from "antd";
import _, { isEqual } from "lodash";
import { useEffect, useMemo, useRef, useState, useCallback } from "react";
import "./index.less";
import TypeExcel from "./type-excel";
import {
  getSeqList,
  getTagList,
} from "@/biz-components/fee-type-Excel/service";
import { plus, round } from "@ey-utils/utils/numberPrecision";
import { toJS } from "@formily/reactive";
import { setThousandth } from "@ey-utils/utils/utils";
import { getUserInfo } from "@/utils/userInfo";
import SelectInvoice from "@/pages/invoice/components/select-invoice";
import { xhrPostJson } from "@/services";
import { apiUrl } from "./service";
import { useFormEffects } from '@formily/react';
import { onFieldChange, onFormMount } from '@formily/core';
import { getAttachmentRemark } from "@/biz-components/fee-type-Excel/hook";
import {
  downloadFileByXHRPost
} from "@/pages/budget-limit-control/tool";

const { TabPane } = Tabs;

interface PaneListProps {
  label: string; // 显示名称
  key: string; // key
  [key: string]: any;
}

interface FeeTypeExcelProps {
  onChange: (v: any) => void;
  billType: string; // 单据类型
  disabled: boolean; // 是否禁用
  value?: any[];
  [key: string]: any;
  madeUser: string; // 申请人
  acctCtgry: string; // 业务申请类型
  acctCo: string; // 记账公司
  needAtt: boolean; // 是否展示附件要求
  needDownload: boolean; // 是否展示模板下载按钮
  overseaDownload: boolean; // 是否展示下载海外模板
}

export const useVisible = (defaultVisible?: boolean): any => {
  const [visible, setVisible] = useState<boolean>(defaultVisible || false);

  const hiddenModal = useCallback((): false => {
    setVisible(false);
    return false;
  }, []);

  const showModal = useCallback((): true => {
    setVisible(true);
    return true;
  }, []);

  return [visible, showModal, hiddenModal];
};

const FeeTypeExcel = (props: FeeTypeExcelProps) => {
  const { billType, disabled, needAtt, needDownload, overseaDownload, onChange, ...otherProps } = props;
  // tab list
  const [tabPaneList, settabPaneList] = useState<PaneListProps[]>([]);
  const [tabMaps, settabMaps] = useState<any>({}); // tag 和 pageDatas的映射
  const [rbrsDetailMaps, setrbrsDetailMaps] = useState<any>({}); // 事项明细map
  const [dict, setDict] = useState<any[]>([]);
  const [shareMetas, setShareMetas] = useState<any[]>([]);

  const excelRef = useRef<any>({});
  const timerRef = useRef<any>();
  const [loading, setLoading] = useState(false);
  const [fullDataUUID, setFullDataUUID] = useState<any>();
  // const exclRef = useRef<any>({});

  const instanceMapRef: any = useRef<any>({});
  const [addVisible, showAddModal, hiddenAddModal] = useVisible(false);
  const requiredData = useRef<any>({});
  // 记录影响item的传参
  const paramsRef = useRef<any>();
  const curForm = useRef<any>();
  useEffect(() => {
    console.log('whx test fee-type-excel, props.value', props.value);
  }, [props?.value]);

  useFormEffects(() => {
    onFormMount((form) => {
      curForm.current = form;
      getTags(form?.values?.acctCtgry || props?.acctCtgry);
    });
    // 记账公司调整
    onFieldChange('acctCo', (field, form) => {
      if (!field?.modified) {
        return;
      }
      console.log('fee-type-excel acctCo', field);
      form.setValuesIn('acctItems', []);
      for (const item of Object.keys(excelRef?.current)) {
        excelRef.current[item] = [];
      }
    });
    // 业务申请类型
    onFieldChange('acctCtgry', (field, form) => {
      if (!field?.modified) {
        return;
      }
      console.log('fee-type-excel acctCtgry', field);
      form.setValuesIn('acctItems', []);
      for (const item of Object.keys(excelRef?.current)) {
        excelRef.current[item] = [];
      }
      getTags(field?.value);
    });
  });

  // useEffect(() => {
  // }, []);

  // useEffect(() => {
  //   if (
  //     props?.value?.length &&
  //     props?.acctCtgry === props?.value[0]?.acctCtgry
  //   ) {
  //     return;
  //   }
  //   getTags();
  // }, [props?.acctCtgry]);
  // // 记账公司变化，清空value
  // useEffect(() => {
  //   if (!props?.acctCo || !props?.value?.length || props?.acctCo === props?.value[0]?.acctCo) {
  //     return;
  //   }
  //   Object(tabMaps)
  //     .keys()
  //     .forEach((it) => {
  //       excelRef.current[it] = [];
  //     });
  //   triggerChange([]);
  // }, [props?.acctCo]);

  const triggerChange = (v) => {
    console.log('fee-type-excel trigger change', v);
    if(isEqual(props.value, v)) {
      return
    }
    if (!v?.length) {
      onChange([]);
    }
    // 增加前端必填项校验
    const nowData = v?.map((it) => {
      if (it.tag && requiredData?.current[it.tag]?.length) {
        it.frontValid = true;
        for (const item of requiredData?.current[it.tag]) {
          if (!it[item]) {
            it.frontValid = false;
            break;
          }
        }
      }
      return it;
    });

    onChange(nowData);
  };
  /**
   * 编辑或者变更业务申请类型的情况下赋值给不同的tag不同数据
   * @param tag
   * @param val
   */
  const handleInitValue = (tag: string, val: any[]) => {
    if (!val?.length) {
      excelRef.current[tag] = [];
      return;
    }
    // 初始化tag
    excelRef.current[tag] = _.cloneDeep(val).filter((it) => {
      return it.tag === tag;
    });
  };
  const getTags = (acctCtgry:string = '') => {
    setLoading(true);
    Promise.allSettled([
      getTagList({ type: billType, acctCtgry: acctCtgry || props?.acctCtgry }),
      getSeqList({}),
    ]).then((allRes) => {
      if (
        allRes?.length === 2 &&
        allRes[0]?.status === "fulfilled" &&
        allRes[0]?.value?.success &&
        allRes[1]?.status === "fulfilled" &&
        allRes[1]?.value?.success
      ) {
        const { result } = allRes[0].value;
        const { result: res1 } = allRes[1].value;
        const tabs: PaneListProps[] = []; // render的tab
        const tagMap = {}; // tag 和 pageDatas的映射
        const rbrsDetailMaps = {}; // 事项明细map
        const seqMap: any = {};
        res1?.forEach((it) => {
          seqMap[it.code] = it.descr;
        });
        result?.map((it) => {
          const {
            code,
            pageDatas,
            name,
            costTypeList,
            costTypeListNo,
            tag,
            ...others
          } = it;
          tabs.push({
            key: code,
            label: name,
            tag,
            seq: seqMap[tag],
          });
          tagMap[tag] = it;
          rbrsDetailMaps[tag] = it;
          handleInitValue(tag, props?.value);
          const requireds: string[] = [];
          pageDatas?.forEach((it) => {
            if (it?.props?.required) {
              requireds.push(it?.key);
            }
          });
          requiredData.current[tag] = requireds;
        });
        tabs?.sort((a, b) => {
          if (+a.seq > +b.seq) {
            return 1;
          }
          return -1;
          // return a.seq
        });

        settabPaneList(tabs);
        settabMaps(tagMap);
        setrbrsDetailMaps(rbrsDetailMaps);
        // setTimeout(() => {
        //     setFullDataUUID(uuidv4());
        // }, 500);
        setLoading(false);
      }
    });
  };

  // 模拟点击屏幕
  const tabClick = (key: any) => {
    setTimeout(() => {
      document.querySelector(`.ant-tabs-tabpane-active .handsontable`)?.click();
    }, 300);
    if (key === 'ZF') { // 杂费不显示油费说明
        curForm.current.setFieldState('displacement',(state:any)=>{
          state.componentProps = {
            ...state.componentProps,
            iconHidden: true
          }
        })
    }else{
        curForm.current.setFieldState('displacement',(state:any)=>{
          state.componentProps = {
            ...state.componentProps,
            iconHidden: false
          }
        })
    }
  };

  // 保存table实例
  const saveInstance = (key: any, instance: any) => {
    instanceMapRef.current[key] = instance;
  };

  // 报账明细字段控制
  const fieldRule = (data:any) => {
    if (data.claimAmt) { // 所有实际报销金额：控制2位小数
      let claimAmt = (Math.floor(parseFloat((data.claimAmt * 100).toPrecision(12))) / 100).toFixed(2);
      data.claimAmt = isNaN(claimAmt)?0:claimAmt;
    }
    if (data.tag === 'CB') { // 餐补
      if (data.matesNr) { // 出行人数：控制正整数
        let matesNr = parseInt(data.matesNr);
        data.matesNr = isNaN(matesNr)?'':(matesNr>0?matesNr:'');
      }
    }
    if (data.tag === 'ZSZF') { // 住宿住房补贴
      if (data.matesNr) { // 房间数：控制正整数
        let matesNr = parseInt(data.matesNr);
        data.matesNr = isNaN(matesNr)?'':(matesNr>0?matesNr:'');
      }
    }
    if(data.tag === 'ZD_CF'){ // 招待餐费
      if (data.particNr) { // 招待人数：控制正整数
        let particNr = parseInt(data.particNr);
        data.particNr = isNaN(particNr)?1:(particNr>0?particNr:1) + '';
      }
    }
    if(data.tag === 'ZD_ZSF'){ // 招待住宿费
      if (data.particNr) { // 招待人数：控制正整数
        let particNr = parseInt(data.particNr);
        data.particNr = isNaN(particNr)?1:(particNr>0?particNr:1) + '';
      }
    }
    if(data.tag === 'ZD_Other'){ // 招待其他
      if (data.particNr) { // 招待人数：控制正整数
        let particNr = parseInt(data.particNr);
        data.particNr = isNaN(particNr)?1:(particNr>0?particNr:1) + '';
      }
    }
    return data;
  };

  const handleValueChange = (data: any[], tag: string) => {
    // excelRef.current[tag] = data;
    const v = [];
    for (const item of Object.keys(excelRef?.current)) {
      if (item && excelRef?.current[item]?.length) {
        for (let it of excelRef.current[item]) {
          if (Object.keys(it).length <= 0) {
            it = fieldRule(it);
            v.push(it);
          } else {
            it = fieldRule(it);
            v.push({ ...it, tag: tabMaps[item]?.tag });
          }
        }
      }
    }
    triggerChange(v);
  };

  /**
   * 保存Meta信息
   * @param data
   * @param tab
   */
  const cacheMetas = (data: any, tag: string) => {
    // todo 数据处理成value 并且调用onchange 要把tag设置进去 acctCtgry,

    handleValueChange(data, tag);
    // if (data?.length > 0) {
    //     // const refData: any[] = data.filter((d: any) => d.code && d.name).map((d: any) => {
    //     //     return { label: d.name, key: d.code, sequence: d.sequence };
    //     // });
    //     // metaExcelRef.current = refData;
    //     // handleValueChange(data, tab);
    //     if (!isEqual(exclRef?.current[tag]?.sort(), data.sort())) {
    //         const temp = _.cloneDeep(data);
    //         exclRef.current[tag] = temp;
    //             // excelRef.current[tab] = temp;
    //         setTimeout(() => {
    //             excelRef.current[tag] = _.cloneDeep(data);
    //             setFullDataUUID(uuidv4());
    //         }, 500);
    //     }
    // }
  };

  // useEffect(() => {
  //     setTimeout(() => {
  //         setFullDataUUID(uuidv4());
  //     }, 500);
  // }, [excelRef?.current]);

  const handleExcelData = (key: string, code: string) => {
    // const { value } = props;
    // const v = toJS(value)?.filter(it => {
    //     return it.tag === key;
    // }) || [];
    // return v;
    // // todo 没有处理value
    return excelRef?.current[key];
  };

  const hideAddModal = () => {
    hiddenAddModal();
  };
  /**
   * 选择发票
   * @param selectRows
   * @param tag
   */
  const tabConfirm = async (selectRows: any[], tag: string) => {
    const ids =
      props?.value?.map((it) => {
        return it.id;
      }) || [];
    if (!selectRows?.length) {
      return;
    }
    const acctItems = selectRows?.filter((it) => !!it.id);
    if (!acctItems?.length) {
      return;
    }
    // const tagD: any = _.cloneDeep(excelRef.current[tag]);
    const newData: any = [];
    acctItems?.forEach((it) => {
      if (ids?.length <= 0 || !ids?.includes(it.id)) {
        const seat: any = {};
        if (it?.seatCategory) {
          seat.seatClass = it?.seatCategory;
          seat.seatClassName = it?.seatCategoryName;
        }
        const d = {
          ...it,
          ...seat,
          tag,
          a: it?.amount || 0,
          rcptFlag: "1",
          rcptFlagName: "是",
          claimAmt: it?.totalAmount || 0,
          frontValid: false,
          expDate: it?.invoiceDate || '', // 实际发生日期默认成费用发生日期
          acctCtgry: curForm?.current?.getValuesIn('acctCtgry'),
          acctCo: curForm?.current?.getValuesIn('acctCo'),
          country: 'CN',
          countryName: '中国',
        };
        newData.push(d);
      }
      return it;
    });
    const { result = [], success } = await  xhrPostJson(apiUrl.sortFapiao, {
      acctItems: newData,
      acctCtgry: curForm?.current?.getValuesIn('acctCtgry') || props?.acctCtgry || '23',
      type: props?.billType,
      tag,
    });
    if (success) {
      const v = props?.value ? toJS(props?.value) : [];
      const data: any[] = v?.length > 0 ? _.cloneDeep([...v]) : [];
      excelRef.current[tag] = excelRef.current[tag] ? excelRef.current[tag].concat(result) : result;
      triggerChange(data.concat(result));
    }
  };
  /**
   * 新增
   * @param tag
   */
  const addConfirm = (tag: string) => {
    const v = props?.value ? toJS(props?.value) : [];
    const data: any[] = v?.length > 0 ? _.cloneDeep([...v]) : [];
    const temp = {
      id: uuidv4(),
      tag,
      rcptFlag: "0",
      rcptFlagName: "否",
      frontValid: false,
      acctCtgry: curForm?.current?.getValuesIn('acctCtgry'),
      acctCo: curForm?.current?.getValuesIn('acctCo'),
      country: 'CN',
      countryName: '中国',
    };
    data.push(temp);
    excelRef.current[tag].push({ ...temp });
    // setTimeout(() => {
    //     setFullDataUUID(uuidv4());
    // }, 100);
    triggerChange(data);
  };
  const handleConfirm = async (selectRows: any[]) => {
    if (!selectRows?.length) {
      return;
    }
    const acctItems = selectRows?.filter((it) => !!it.id);
    if (!acctItems?.length) {
      return;
    }
    xhrPostJson(apiUrl.sortFapiao, {
      acctItems,
      acctCtgry: curForm?.current?.getValuesIn('acctCtgry') || props?.acctCtgry,
      type: props?.billType,
    }).then((res) => {
      if (res?.success) {
        const { result = [] } = res;
        const v = props?.value ? toJS(props?.value) : [];
        const data: any[] = v?.length > 0 ? _.cloneDeep([...v]) : [];
        const ids =
          props?.value?.map((it) => {
            return it.id;
          }) || [];
        const tagDatas: any[] = [];
        result?.forEach((it) => {
          if (ids?.length <= 0 || !ids?.includes(it.id)) {
            const seat: any = {};
            if (it?.seatCategory) {
              seat.seatClass = it?.seatCategory;
              seat.seatClassName = it?.seatCategoryName;
            }
            const temp = {
              ...it,
              ...seat,
              claimAmt: it?.totalAmount || 0,
              rcptFlag: "1",
              rcptFlagName: "是",
              frontValid: false,
              acctCtgry: curForm?.current?.getValuesIn('acctCtgry'),
              acctCo: curForm?.current?.getValuesIn('acctCo'),
              expDate: it?.invoiceDate || '', // 实际发生日期默认成费用发生日期
              country: 'CN',
              countryName: '中国',
            };
            tagDatas.push(temp);
            data.push(temp);
          }
        });
        const ds: any = {};
        tagDatas.forEach((it) => {
          if (ds[it.tag]) {
            ds[it.tag].push(it);
          } else {
            ds[it.tag] = [it];
          }
        });
        Object.keys(ds).forEach((it) => {
          excelRef.current[it] = excelRef.current[it].concat(ds[it]);
        });
        triggerChange(data);
        // setTimeout(() => {
        //     setFullDataUUID(uuidv4());
        // }, 500);
      }
    });
  };
  const handleSelectInvoice = () => {
    showAddModal();
  };

  // 下载模板
  const downloadTemplate = () => {
    // todo 下载模板
    console.log("下载模板");

    const params = {
      acctCo: curForm?.current?.getValuesIn('acctCo'),
      type: props?.pageType,
      acctCtgry: curForm?.current?.getValuesIn('acctCtgry'),
    };
    if (props?.bdgtAcct && props?.divideType !== 'public') {
      params.bdgtAcct = props?.bdgtAcct;
      params.bdgtAcctName = props?.bdgtAcctName;
    }
    if (props?.divideType === 'public') {
      params.bizCtgry = curForm?.current?.getValuesIn('bizCtgry');
      params.bizCtgryName = curForm?.current?.getValuesIn('bizCtgryName');
    }
    if(props.downloadParams) {
      props.downloadParams?.forEach((key) => {
        params[key] = curForm?.current?.getValuesIn(key) || '';
      })
    }
    downloadFileByXHRPost(props?.downloadUrl || apiUrl.downtemplate, params);
  };

  // 下载海外模板
  const downloadTemplate1 = () => {
    // todo 下载模板
    console.log("下载海外模板");

    const params = {
      acctCo: curForm?.current?.getValuesIn('acctCo'),
      type: props?.pageType1,
      acctCtgry: curForm?.current?.getValuesIn('acctCtgry'),
    };
    if (props?.bdgtAcct && props?.divideType !== 'public') {
      params.bdgtAcct = props?.bdgtAcct;
      params.bdgtAcctName = props?.bdgtAcctName;
    }
    if (props?.divideType === 'public') {
      params.bizCtgry = curForm?.current?.getValuesIn('bizCtgry');
      params.bizCtgryName = curForm?.current?.getValuesIn('bizCtgryName');
    }
    if(props.downloadParams) {
      props.downloadParams?.forEach((key) => {
        params[key] = curForm?.current?.getValuesIn(key) || '';
      })
    }
    downloadFileByXHRPost(props?.downloadUrl || apiUrl.downtemplate, params);
  };

  // 渲染excel
  const typeExcelRender = (it: any, fUUID: string) => {
    return (
      <TypeExcel
        disabled={disabled}
        saveInstance={saveInstance}
        cacheMetas={cacheMetas}
        detailDataSource={handleExcelData(it.tag || it.key, it.key)}
        modelMeta={tabMaps[it?.tag]}
        fullDataUUID={fUUID}
        dictMaps={rbrsDetailMaps[it?.tag]}
        tabConfirm={tabConfirm}
        addConfirm={addConfirm}
        shareMetas={shareMetas}
        acctCo={curForm?.current?.getValuesIn('acctCo')}
      />
    );
  };

  const tabLabelRender = (it) => {
    const { key, tag } = it || {};
    let count = 0;
    let length = 0;
    const styleColor: any = {};
    if (excelRef?.current[tag]?.length) {
      const trueData = excelRef?.current[tag]?.filter((item) => {
        return Object.keys(item).length > 0;
      });
      count = trueData.reduce((total: number, cur: any) => {
        return round(plus(total, cur && cur.claimAmt ? cur.claimAmt : 0), 2);
      }, 0);
      length = trueData.length;
      // 判断必填项是否都已经填完
      for (const item of trueData) {
        for (const i of requiredData?.current[it.tag]) {
          if (!item[i]) {
            styleColor.color = "red";
            break;
          }
        }
      }
    }
    // return (
    //     <Badge count={length}>
    //         <span>
    //         {it.label}
    //         {count ? `(${count})` : ''}
    //         </span>
    // </Badge>
    // )
    return (
      <div>
        <div style={styleColor}>
          {it.label}({length})
        </div>
        <div style={{ textAlign: "right", fontSize: "12px" }}>
          {setThousandth(count)}
        </div>
      </div>
    );
  };

  const TabsRender = () => {
    return (
      <Tabs defaultActiveKey="model-excel" onTabClick={tabClick} size="small">
        {tabPaneList?.length
          ? tabPaneList.map((it: PaneListProps) => {
              return (
                <TabPane tab={tabLabelRender(it)} key={it.tag} forceRender>
                  {typeExcelRender(it, fullDataUUID)}
                </TabPane>
              );
            })
          : null}
      </Tabs>
    );
  };

  const renderTitle = () => {
    return !disabled ? (
      <Space>
        <Button onClick={handleSelectInvoice}>选择发票</Button>
      </Space>
    ) : null;
  };

  const renderBtnModal = () => {
    let content = getAttachmentRemark(billType);
    const contentNew = (<div>
      {
        content.map((item,index)=>{
          return(
            <p key={index} dangerouslySetInnerHTML={{ __html: item}}></p>
          ) 
        })
      }
    </div>)
    return needAtt?(
      <Popover placement="right" content={contentNew} title="附件要求" trigger="click" overlayStyle={{zIndex: 999}}>
        <Button style={{ marginLeft: 5 }}>附件要求</Button>
      </Popover>
    ):null;
  };

  // 模板下载
  const renderDownloadBtn = () => {
    return needDownload?(
      <Button style={{ marginLeft: 5 }} onClick={downloadTemplate}>差旅费报销明细表</Button>
    ):null;
  };

  // 海外报销模板下载
  const renderDownloadBtn1 = () => {
    return overseaDownload?(
      <Button style={{ marginLeft: 5 }} onClick={downloadTemplate1}>差旅费报销明细表（境外报销专用）</Button>
    ):null;
  };

  return (
    <Spin spinning={loading}>
      <div>
        {renderTitle()}
        {renderDownloadBtn()}
        {renderDownloadBtn1()}
        {renderBtnModal()}
        {TabsRender()}
        <SelectInvoice
          elStatus="N"
          addVisible={addVisible}
          hiddenAddModal={hideAddModal}
          confirm={handleConfirm}
          value={[]}
          acctCo={curForm?.current?.getValuesIn('acctCo')}
        />
      </div>
    </Spin>
  );
};

export default FeeTypeExcel;
